package com.coocaa.ops.common.tool.json;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer;
import com.coocaa.ops.common.tool.reflect.ReflectUtil;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.*;

/**
 * @author tangminghong
 * @date 2020-06-10 18:09
 */
public class JsonUtil {

    private static SerializeConfig mapping = new SerializeConfig();

    private static String dateFormat = "yyyy-MM-dd HH:mm:ss";

    private JsonUtil() {
    }

    static {
        mapping.put(Date.class, new SimpleDateFormatSerializer(dateFormat));
    }

    public static <T> List<T> convertToList(String jsonString, Class<T[]> cls) {
        if (jsonString == null) {
            return null;
        }
        List<T> list = null;
        try {
            ObjectMapper mapper = new ObjectMapper();
            mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            list = Arrays.asList((T[]) mapper.readValue(jsonString, cls));
        } catch (JsonParseException var5) {
            var5.printStackTrace();
        } catch (JsonMappingException var6) {
            var6.printStackTrace();
        } catch (IOException var7) {
            var7.printStackTrace();
        }

        return list;
    }

    public static <T> List<T> json2ObjectLists(String jsonString, Class<?> cls) {
        ArrayList list = null;

        try {
            JSONArray jsonArray = JSON.parseArray(jsonString);
            if (jsonArray != null && jsonArray.size() > 0) {
                list = new ArrayList();
                for (int i = 0; i < jsonArray.size(); ++i) {
                    JSONObject object = jsonArray.getJSONObject(i);
                    Object model = JSONObject.toJavaObject(object, cls);
                    list.add(model);
                }
            }
        } catch (Exception var7) {
            var7.printStackTrace();
        }
        return list;
    }

    public static Object json2Object(String jsonString, Class<?> classOfT) {
        return JSON.toJavaObject(JSON.parseObject(jsonString), classOfT);
    }

    public static Map<String, String> json2Map(String jsonString) {
        return (Map) JSON.parse(jsonString);
    }

    public static Map<String, Object> json2MapObj(String jsonString) {
        return (Map) JSON.parse(jsonString);
    }

    public static List<Map<String, Object>> json2Maps(String jsonString) {
        return (List) JSON.parse(jsonString);
    }

    public static List<Map<String, Integer>> json2MapsInt(String jsonString) {
        return (List) JSON.parse(jsonString);
    }

    public static String obj2Json(Object obj) {
        return JSON.toJSONString(obj, mapping, new SerializerFeature[0]);
    }

    /**
     * 避免出现<code>
     * "$ref":"$.data[0].task.OBJECTS[0]"
     * </code>
     *
     * @param obj
     * @return
     */
    public static String obj2JsonDisableCircularRef(Object obj) {
        return JSON.toJSONString(obj, mapping, SerializerFeature.DisableCircularReferenceDetect);
    }

    public static String getListToTreeJson(List<?> list, String strPK, String strFK, Object object) throws Exception {
        StringBuffer sb = new StringBuffer();
        sb.append("[");
        sb.append(generateTreeJson(list, strPK, strFK, object));
        sb.append("]");
        return sb.toString().replaceAll(",\"children\":\\[]", "").replaceAll(",]", "]");
    }

    private static String generateTreeJson(List<?> list, String strPK, String strFK, Object object) throws Exception {
        StringBuffer buf = new StringBuffer();
        Object obj = null;
        Iterator var6;
        Object entity;
        Class clazz;
        Field[] fieldList;
        Object name;
        int size;
        if (object == null) {
            var6 = list.iterator();

            while (true) {
                do {
                    if (!var6.hasNext()) {
                        return buf.toString();
                    }

                    entity = var6.next();
                    obj = entity;
                    clazz = entity.getClass();
                    fieldList = clazz.getDeclaredFields();
                    name = ReflectUtil.invokeBeanMethod(entity, "get" + StringUtils.capitalize(strFK));
                } while (!"0".equals(name.toString()));
                buf.append("{");
                int i = 0;
                for (size = fieldList.length; i < size; ++i) {
                    Field fieldSub = fieldList[i];
                    String filedName = fieldSub.getName();
                    if (!"serialVersionUID".equals(filedName)) {
                        Object value = ReflectUtil.invokeBeanMethod(obj, "get" + StringUtils.capitalize(fieldSub.getName()));
                        buf.append("\"").append(fieldSub.getName()).append("\"").append(":\"").append(value == null ? "" : value).append("\"");
                        if (i < size - 1) {
                            buf.append(",");
                        }
                    }
                }
                buf.append(",\"children\":[");
                buf.append(generateTreeJson(list, strPK, strFK, obj));
                buf.append("]},");
            }
        } else {
            var6 = list.iterator();

            while (true) {
                Object pk;
                do {
                    if (!var6.hasNext()) {
                        return buf.toString();
                    }

                    entity = var6.next();
                    obj = entity;
                    clazz = entity.getClass();
                    fieldList = clazz.getDeclaredFields();
                    name = ReflectUtil.invokeBeanMethod(entity, "get" + StringUtils.capitalize(strFK));
                    pk = ReflectUtil.invokeBeanMethod(object, "get" + StringUtils.capitalize(strPK));
                } while (!name.equals(pk));

                buf.append("{");
                size = fieldList.length;

                for (int index = 0; index < size; ++index) {
                    Field fieldSub = fieldList[size];
                    String filedName = fieldSub.getName();
                    if (!"serialVersionUID".equals(filedName)) {
                        Object value = ReflectUtil.invokeBeanMethod(obj, "get" + StringUtils.capitalize(fieldSub.getName()));
                        buf.append("\"").append(fieldSub.getName()).append("\"").append(":\"").append(value == null ? "" : value).append("\"");
                        if (size < size - 1) {
                            buf.append(",");
                        }
                    }
                }

                buf.append(",\"children\":[");
                buf.append(generateTreeJson(list, strPK, strFK, obj));
                buf.append("]},");
            }
        }
    }


}
